﻿#region Using namespaces

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

using BOL.Apps.GeneNetworkBrowser;
using BOL.Apps.GeneNetworkBrowser.Controls;

using GraphSharp.Controls;

#endregion

namespace BOL.Apps.GeneNetworkBrowser.ViewModels
{
    public sealed class NetworkDocumentViewModel : DocumentViewModel
    {
        #region Private variables

        private Network _network;
        private LayoutAlgorithmType _layoutAlgorithmType;
        private static NetworkGraphLayout _networkGraphLayout = null;  

        #endregion

        #region Public properties

        public Network Network
        {
            get { return _network; }
            set
            {
                if (value != _network)
                {
                    _network = value;
                    IsChanged = true;
                    OnPropertyChanged("Network");
                }
            }
        }

        public LayoutAlgorithmType LayoutAlgorithmType
        {
            get { return _layoutAlgorithmType; }
            set
            {
                _layoutAlgorithmType = value;
                OnPropertyChanged("LayoutAlgorithmType");
            }
        }

        public static readonly DependencyProperty NetworkGraphLayoutProperty =
            DependencyProperty.RegisterAttached("NetworkGraphLayout",
            typeof(NetworkGraphLayout), 
            typeof(NetworkDocumentViewModel),
            new FrameworkPropertyMetadata(OnNetworkGraphLayoutChanged));

        public static void SetNetworkGraphLayout(DependencyObject element, NetworkDocument value)  
        {
            element.SetValue(NetworkGraphLayoutProperty, value);  
        }

        public static NetworkDocument GetNetworkGraphLayout(DependencyObject element)  
        {
            return (NetworkDocument)element.GetValue(NetworkGraphLayoutProperty);  
        }

        public static void OnNetworkGraphLayoutChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            _networkGraphLayout = obj as NetworkGraphLayout;
        }

        #endregion

        #region Constructor

        public NetworkDocumentViewModel(Network network, string filePath)
            : base(filePath)
        {
            _layoutAlgorithmType = LayoutAlgorithmType.CompoundFDP;
            Network = network;
        }

        #endregion

        #region Public methods

        public void ChangeVertexColor(string attributeName, string minColorName, string maxColorName)
        {
            VertexControl vc;
            var genes = _networkGraphLayout.Graph.Vertices;
            var min = genes.Min(x => (double)x.Attributes[attributeName]);
            var denominator = genes.Max(x => (double)x.Attributes[attributeName]) - min;

            foreach (var gene in genes)
            {
                vc = _networkGraphLayout.GetVertexControl(gene);

                var minColor = System.Drawing.Color.FromName(minColorName);
                var minH = (double)minColor.GetHue() / 360.0;
                var maxColor = System.Drawing.Color.FromName(maxColorName);
                var maxH = (double)maxColor.GetHue() / 360.0;

                var value = (gene.Attributes[attributeName] - min) / denominator;

                double h = (value < 0.5) ? minH : maxH;
                double s = (value < 0.5) ? (0.5 - value) * 2 : (value - 0.5) * 2;
                double l = 0.5;
                    
                vc.Background = new SolidColorBrush(Converters.ColorSystems.FromHSL(h, s, l));
            }
        }

        public void ChangeVertexFontSize(string attributeName, int minFontSize, int maxFontSize)
        {
            VertexControl vc;
            var genes = _networkGraphLayout.Graph.Vertices;
            var min = genes.Min(x => (double)x.Attributes[attributeName]);
            var denominator = genes.Max(x => (double)x.Attributes[attributeName]) - min;
            var fontSize = maxFontSize - minFontSize;

            foreach (var gene in genes)
            {
                vc = _networkGraphLayout.GetVertexControl(gene);
                var value = ((double)gene.Attributes[attributeName] - min) / denominator;

                vc.FontSize = value * fontSize + minFontSize;
            }
        }

        //public void ChangeVertexPadding(string attributeName, int maxPadding)
        //{
        //    VertexControl vc;
        //    var genes = _networkGraphLayout.Graph.Vertices;
        //    var min = genes.Min(x => (double)x.Attributes[attributeName]);
        //    var denominator = genes.Max(x => (double)x.Attributes[attributeName]) - min;

        //    foreach (var gene in genes)
        //    {
        //        vc = _networkGraphLayout.GetVertexControl(gene);
        //        var value = ((double)gene.Attributes[attributeName] - min) / denominator;

        //        var a = value * maxPadding;
        //        if (a != 0 || !Double.IsNaN(a))
        //            vc.FontSize = value * maxPadding + 5;
        //        else
        //            vc.FontSize = 5;
        //        //vc.Padding = new Thickness(value * maxPadding);
        //    }
        //}


        #endregion
    }
}
